package com.zy.utils;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.extern.java.Log;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.UUID;


@Log
@Configuration
@Component
public class MongodbUtils {


    @Resource
    private GridFsTemplate gridFsTemplate;

    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * @param file 上传的文件
     * @return 上传文件的objectId
     * @throws Exception 读取文件都会遇到的异常
     */
    public Object upload(@RequestParam("file") MultipartFile file) throws Exception {
        log.info("上传文件");
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            return "请选择上传的文件";
        }
        // 随机生成文件名字，防止重复
        UUID uuid = UUID.randomUUID();
        String s = uuid.toString().replaceAll("-", "");
        String[] split = originalFilename.split("\\.");
        originalFilename = s.substring(18) + "." + split[split.length - 1];
        log.info("随机生成后的文件名字" + originalFilename);

        InputStream stream = file.getInputStream();
        String contentType = file.getContentType();
        ObjectId store = gridFsTemplate.store(stream, originalFilename, contentType);
        log.info("store:" + store);
        return store.toString();
    }

    /**
     * 下载直接 get 请求调用
     * 回显 需要特殊方法
     * 例如图片回显 <img src="http://127.0.0.1:8081/download?file=${ObjectId}"></img>
     * 当中的ObjectId是文件对应的图片id 路径就是访问的本地下载的页面
     *
     * @param ObjectId 查询mongodb库里文件的id
     * @param response 相应前台
     * @throws Exception io异常
     */
    public void down(String ObjectId, HttpServletResponse response) throws Exception {
        log.info("开始下载文件......");
        Query id = Query.query(Criteria.where("_id").is(ObjectId));
        GridFSFile fsFiles = gridFsTemplate.findOne(id);
        if (fsFiles == null) {
            log.warning("没有获取到文件");
            return;
        }
        String s = fsFiles.getFilename();
        log.info("文件名字" + s);
        if (fsFiles.getMetadata() == null) {
            log.warning("文件类型空指针");
            return;
        }
        String contentType = fsFiles.getMetadata().get("_contentType").toString();
        log.info("文件类型" + contentType);
        //通知下载
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(s, "UTF-8") + "\"");
        GridFSBucket fsBucket = GridFSBuckets.create(mongoTemplate.getDb());
        GridFSDownloadStream downloadStream = fsBucket.openDownloadStream(fsFiles.getObjectId());
        //获取mongodb的资源
        GridFsResource resource = new GridFsResource(fsFiles, downloadStream);
        //文件输入流
        InputStream inputStream = resource.getInputStream();
        //文件输出流
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(inputStream, outputStream);
        //关流
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }

    /*
    删除mongo里的文件
     */
    public String deleteFile(String objectId) {
        log.info("开始删除文件......");
        Query id = Query.query(Criteria.where("_id").is(objectId));
        GridFSFile fsFiles = gridFsTemplate.findOne(id);
        if (fsFiles == null) {
            log.warning("没有获取到文件");
            return "文件不存在";
        }
        GridFSBucket bucket = GridFSBuckets.create(mongoTemplate.getDb());
        bucket.delete(new ObjectId(objectId));
        return "删除成功";
    }
}


